#include "Object.h"

//------------------------------------------------------------------------------

Object::Object(ParticleSystem* _particleSystem)
{
	particleSystem = _particleSystem;
	//particleSystem->addObject(this);
}

//------------------------------------------------------------------------------

void Object::verlet()
{
	set<Particle*>::iterator p;
	for(p = particle.begin(); p != particle.end(); ++p) {
		(*p)->verlet(particleSystem->timeStep);
	}
	updateCollisionSystem();
}

//------------------------------------------------------------------------------

void Object::satisfyConstraints()
{
	set<Constraint*>::iterator c;
	for(c = constraint.begin(); c != constraint.end(); ++c) {
		(*c)->satisfyConstraint();
	}
	updateCollisionSystem();
}

//------------------------------------------------------------------------------

void Object::setAcc(const Vector3& acc)
{
	set<Particle*>::iterator p;
	for(p = particle.begin(); p != particle.end(); ++p) {
		(*p)->acceleration = acc;
	}
}

//------------------------------------------------------------------------------

void Object::setDamping(double damping)
{
	set<Particle*>::iterator p;
	for(p = particle.begin(); p != particle.end(); ++p) {
		(*p)->damping = damping;
	}
}

//------------------------------------------------------------------------------

/*
 * Return the envelope that best approximates the shape of this object.
 * This set of points will be used to check for collision against other objects.
 * The cheapest approximation would probably be to return the AABB (axis-aligned bounding box) of this object.
 * The particles that make up the envelope might be modified (moved) to handle the collision. It is up to subsequent relaxations to enforce the constraints that maintain the object's shape.
 */
const set<Particle*>& Object::getEnvelope()
{
	return particle;
}

//------------------------------------------------------------------------------

Object::~Object()
{
	// Remove this object from other systems
	if(particleSystem)
		particleSystem->removeObject(this);
	if(collisionSystem)
		collisionSystem->removeObject(this);

	// Free particles
	set<Particle*>::iterator p;
	for(p = particle.begin(); p != particle.end(); ++p)
		delete (*p);

	// Free constraints
	set<Constraint*>::iterator c;
	for(c = constraint.begin(); c != constraint.end(); ++c)
		delete (*c);

	set<Triangle*>::iterator t;
	for(t = triangle.begin(); t != triangle.end(); ++t)
		delete (*t);
}

//------------------------------------------------------------------------------

void Object::updateCollisionSystem()
{
	set<Triangle*>::iterator t;
	for(t = triangle.begin(); t != triangle.end(); ++t) {
		(*t)->updateAABB();
		collisionSystem->update(*t);
	}
}
